package com.example.oauth2.service;

import com.example.oauth2.entry.User;
import com.example.oauth2.repository.UserRepository;
import com.example.oauth2.util.APIResponse;
import com.example.oauth2.vo.UserVO;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Component
public class UserService {

    private Logger logger = LogManager.getLogger(getClass());

    @Autowired
    private UserRepository userRepository;

    private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    public APIResponse getUserList() {
        APIResponse apiResponse = new APIResponse();
        apiResponse.setResponseCode(APIResponse.OK);

        List<User> userList = userRepository.findAll();
        List<User> result = userList.stream().map(u -> {
            u.setPassword("");
            return u;
        }).collect(Collectors.toList());
        apiResponse.setData(result);
        return apiResponse;
    }

    public APIResponse addUser(UserVO userVO) {
        APIResponse apiResponse = new APIResponse();
        apiResponse.setResponseCode(APIResponse.OK);

        //此处忽略重复用户校验

        try {
            User user = new User();
            user.setUserName(userVO.getUserName());
            user.setPassword(passwordEncoder.encode(userVO.getPassword()));
            user.setRoles(userVO.getRoles());
            user.setLastPswdChangeTimestamp(Instant.now().toString());
            userRepository.save(user);
        } catch (Exception e) {
            Throwable t = Optional.ofNullable(e.getCause()).orElse(e);
            String errorMessage = Optional.ofNullable(t.getMessage()).orElse("Internal exception: " + e);
            String traceMessage = Arrays.asList(e.getStackTrace()).stream().map(trace -> trace.toString()).collect(Collectors.joining("\nat "));
            logger.log(Level.ERROR, errorMessage + "\nat " + traceMessage);
            apiResponse.setResponseCode(APIResponse.ERROR);
        }
        return apiResponse;
    }

}
